哈囉大家好,今天我們又重啟了extension的開發,話說最近真忙啊,不過就算再忙專案也會進行下去開發完成的。
今天開始,我們會在使用react的webview裡引用Ant Design Mobile來進行Webview的元件開發。
為什麼要特別使用mobile的ui元件呢?在我們的Extension的使用情境裡,我們會在使用者的editor group裡多開一個editor,這個editor最多只會佔用使用者一半的視窗,寬度相較一般網頁也會至少縮減一半。在這種寬高比例下,處理Router導航的元件選用mobile的ui元件會比某些desktop的元件來得適合。在另外一種情境,如表單處理,我們則是會繼續使用Desktop的UI元件。
讓我們開始配置UI元件吧!
首先,進入我們webivew專案的資料夾下面
cd webview
接著,安裝antd-mobile的library
yarn add antd-mobile
好的,引入library之後,我們一般可以直接在app.css直接引用整個library的css檔案,如下所示。
@import '~antd-mobile/dist/antd-mobile.css';
不過這樣會一次引入所有的css設定,而我們使用的元件並不多。實務上,我們會根據使用多少ui元件按需引入css的設定。為了這個需求,我們會使用到babel-plugin-import
這個套件,幫助我們根據引入的library的元件來決定引用多少元件的css設定。
為了使用babel-plugin-import這個工具,我們會使用到create-react-app預設以外的客製化設定。
因為要使用create-react-app預設以外的webpack或babel設定,我們會使用react-app-rewired
這個工具,目的是覆蓋掉create-react-app原本使用的webpack或babel的設定檔,以使用預設以外的客製化設定。因為react-app-rewired
這個套件在2.x版的一些issue,這裡我們會再安裝customize-cra
這個工具配合rewired一起使用。
yarn add -D react-app-rewired customize-cra babel-plugin-import
安裝完後,我們需要在根目錄下創建一個config-override.js檔案,並在配置使用客製化的設定。
const { override, fixBabelImports } = require('customize-cra');
module.exports = override(
fixBabelImports('import', {
libraryName: 'antd-mobile',
style: 'css',
}),
);
接著,我們將package.json裡Create-React-App預設使用的react-scripts改為react-app-rewired。
{
...
"scripts": {
"start": "react-app-rewired start",
"build": "react-app-rewired build && cp -r ./build ../out && rm -rf ./build",
"test": "react-app-rewired test",
...
}
...
}
本來package.json裡的scripts會有一個以eject為名的script,但使用eject這個script後,我們沒辦法隨著升級create react app更新eject出來的設定檔。react-app-rewired就是為了解決eject
這個預設提供的script的不足所開發的套件,因此,這裡我們直接刪除eject的script即可。
現在每次我們使用npm script,如yarn build
時,就會自動套用到babel-plugin-import
裡的設定,引用所需的css。
好的,環境已經設定好了,讓我們馬上來使用Ant Design Mobile的元件來取代前面介紹router時使用的Navigator的連結吧!
目前我們的Webview頁面功能相對單純,我們會使用SegmentedControl來處理router的換頁。
讓我們在src/component資料夾下面創造一個navigator的資料夾,並在資料夾下創建兩個文件
.
├── index.ts
└── navigator.tsx
首先是最重要的navigator.tsx,我們會引用SegmentedControl這個元件,並使用react router的useHistory hook,在切換頁籤時,導航應用程式到對應的頁面。
import * as React from 'react';
import { SegmentedControl } from 'antd-mobile';
import { useHistory } from 'react-router-dom';
export default function SegmentedNavigator() {
const history = useHistory();
const onValueChange = (value: string) => {
history.push(`/${value.toLowerCase()}`);
}
return (
<SegmentedControl
values={['Snippets', 'Extensions']}
selectedIndex={0}
onValueChange={onValueChange}
/>
);
}
接著,我們在index.ts匯出這個component
import SegmentedControl from './navigator';
export default SegmentedControl;
好的,完成Navigator之後,現在我們就可以在Router頁面使用這個元件了,但首先讓我們引用WingBlank這個元件,讓我們將背景色置換成對視覺友善的灰色。
import React from 'react';
import {
useHistory,
HashRouter as Router,
Switch,
Route,
Link
} from "react-router-dom";
import { WingBlank } from 'antd-mobile';
export default function RouterPage() {
return (
<Router>
<WingBlank size="lg" className="wing-blank">
<div>
...
</div>
</WingBlank>
</Router>
);
}
接下來,我們在router的目錄下創建router.css設定Wingblank的padding間距
.wing-blank {
padding: 1em 0;
}
現在我們引用router.css,並引使用剛才完成的Navigator元件在router上面。
import { WingBlank } from 'antd-mobile';
import React from 'react';
import {
useHistory,
HashRouter as Router,
Switch,
Route,
Link
} from "react-router-dom";
import SegmentedNavigator from '../components/navigator';
import './router.css';
export default function RouterPage() {
return (
<Router>
<WingBlank size="lg" className="wing-blank">
<div>
<nav>
<SegmentedNavigator />
</nav>
<Switch>
<Route path="/snippets">
<Snippets />
</Route>
<Route path="/extensions">
<Extensions />
</Route>
<Route path="/">
<Snippets />
</Route>
</Switch>
</div>
</WingBlank>
</Router>
);
}
好了,完成以後,讓我們檢視在網頁上呈現的結果吧!
現在我們可以看到mobile style的tab,讓我們檢視下切換標籤後的結果。
好的,以上就是今天分享的內容,環境設定與實際元件的實際使用。
明天我們會繼續開發Webview裡的Snippet管理元件,我們明天見,謝謝大家。
IT邦幫忙的Markdown語法目前並沒有支援jsx跟tsx的語法,上面是先使用js的markdown格式來展示。可能有些地方的語法hightlight不太自然,後續系列完成後會將前面系列文一併調整。